package com.example.flickertext.widget

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import com.example.flickertext.R
import kotlin.math.abs
import kotlin.math.min

/**
 * author : king_nina
 * e-mail : 13450414852@163.com
 * date   : 2021/12/9
 * desc   :
 */
private const val VERTICALOFFSET = 40f

class FlickerText : View {

    private var minWidth = 0
    private var minHeight = 0

    private lateinit var paint: Paint
    private var textSize = 120
    private var showText: String = ""
    private var normalColor = Color.parseColor("#F0F0F2")
    private var flickColor = Color.parseColor("#DCDCDC")
    private var flickPercent = 0.16f
    private var clipLeft = -VERTICALOFFSET
    private var path: Path = Path()

    constructor(context: Context) : super(context) {
        init(null, 0, 0)
    }

    constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
        init(attributeSet, 0, 0)
    }

    constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(
        context,
        attributeSet,
        defStyleAttr
    ) {
        init(attributeSet, defStyleAttr, 0)
    }

    private fun init(attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) {
        // 获取配置属性
        context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.FlickerText,
            0, 0
        ).apply {
            try {
                showText = getString(R.styleable.FlickerText_text).toString()
                textSize =
                    getDimensionPixelSize(R.styleable.FlickerText_text_size, textSize)
                normalColor = getColor(R.styleable.FlickerText_text_normal_color, normalColor)
                flickColor = getColor(R.styleable.FlickerText_text_flick_color, flickColor)
                flickPercent = getFloat(R.styleable.FlickerText_flick_precent, flickPercent)
            } finally {
                recycle()
            }
        }

        // 初始化画笔相关
        paint = Paint()
        paint.isAntiAlias = true
        paint.textSize = textSize.toFloat()
        val textBound = Rect()
        paint.getTextBounds(showText, 0, showText.length, textBound)
        minWidth = textBound.width()
        minHeight = textBound.height()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val widthSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)
        var width = 0
        var height = 0
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize
        } else {
            width = min(widthSize, minWidth)
        }
        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize
        } else {
            height = min(heightSize, minHeight)
        }
        setMeasuredDimension(width, height)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        paint.color = normalColor
        canvas?.drawText(showText, 0f, height * 0.5f, paint)

        path.reset()
        path.moveTo(clipLeft, 0f)
        path.lineTo(clipLeft + width * flickPercent, 0f)
        path.lineTo(clipLeft + width * flickPercent + VERTICALOFFSET, height.toFloat())
        path.lineTo(clipLeft + VERTICALOFFSET, height.toFloat())
        paint.color = flickColor
        canvas?.clipPath(path)
        canvas?.drawText(showText, 0f, height * 0.5f, paint)

        clipLeft += 5f
        if (clipLeft > width) {
            clipLeft = -VERTICALOFFSET
        }
        invalidate()
    }
}